package Example;

import java_cup.runtime.SymbolFactory;
%%
%cup
%class Scanner
%{
	public Scanner(java.io.InputStream r, SymbolFactory sf){
		this(r);
		this.sf=sf;
	}
	private SymbolFactory sf;
%}
%eofval{
    return sf.newSymbol("EOF",sym.EOF);
%eofval}

LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace     = {LineTerminator} | [ \t\f]

Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}

TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent       = ( [^*] | \*+ [^/*] )*

Identifier = [:jletter:] [:jletterdigit:]*

DecIntegerLiteral = 0 | [1-9][0-9]*

%state STRING

%%

<YYINITIAL>{
	/* identificadores */
	{Identifier} { return sf.newSymbol("Identificador", sym.IDENTIFICADOR); }

	/* literais */
	{DecIntegerLiteral} { return sf.newSymbol("Numero Inteiro", sym.INTEIRO, new Integer(yytext())); }
	\" { string.setLength(0); yybegin(STRING); }
	
	/* operadores */
	"||" { return sf.newSymbol("Ou Logico",sym.OU_LOGICO); }
	"&&" { return sf.newSymbol("E Lgico",sym.E_LOGICO); }
	"==" { return sf.newSymbol("Igual Comparacao",sym.IGUAL); }
	"!=" { return sf.newSymbol("Diferente",sym.DIFERENTE); }
	"<"  { return sf.newSymbol("Menor",sym.MENOR); }
	"<=" { return sf.newSymbol("Menor ou Igual",sym.MENOR_IGUAL); }
	">"  { return sf.newSymbol("Maior",sym.MAIOR); }
	">=" { return sf.newSymbol("Maior ou Igual",sym.MAIOR_IGUAL); }
	"+"  { return sf.newSymbol("Mais",sym.MAIS); }
	"-"  { return sf.newSymbol("Menos",sym.MENOS); }
	"*"  { return sf.newSymbol("Menos",sym.VEZES); }
	"/"  { return sf.newSymbol("Divide",sym.DIVIDE); }
	"%"  { return sf.newSymbol("Modulo",sym.MODULO); }
	"!"  { return sf.newSymbol("Not",sym.NOT); }
	"="  { return sf.newSymbol("Igual Atribuicao",sym.IGUAL_ATRIB); }
	";"  { return sf.newSymbol("Ponto-e-virgula",sym.PONTO_VIRGULA); }
	"{"  { return sf.newSymbol("Chave Esquerda",sym.CHAVE_ESQ); }
	"}"  { return sf.newSymbol("Chave Direita",sym.CHAVE_DIR); }
	"["  { return sf.newSymbol("Colchete Esquerdo",sym.COLCHETE_ESQ); }
	"]"  { return sf.newSymbol("Colchete Direito",sym.COLCHETE_DIR); }
	"("  { return sf.newSymbol("Parentese Esquerdo",sym.PARENT_ESQ); }
	")"  { return sf.newSymbol("Parentese Direito",sym.PARENT_DIR); }
	
	/* palavras reservadas */
	"int" { return sf.newSymbol("Int",sym.INT); }
	"string" { return sf.newSymbol("String",sym.STRING); } 
	"boolean" { return sf.newSymbol("Boolean",sym.BOOLEAN); }
	"void" { return sf.newSymbol("Void",sym.VOID); }	
	"true" { return sf.newSymbol("True",sym.TRUE); }
	"false" { return sf.newSymbol("False",sym.FALSE); }
	"if" { return sf.newSymbol("If",sym.IF); }
	"else" { return sf.newSymbol("Else",sym.ELSE); }
	"while" { return sf.newSymbol("While",sym.WHILE); }
	"ref" { return sf.newSymbol("Ref",sym.REF); }
	"return" { return sf.newSymbol("Return",sym.RETURN); }

	/* comentarios */
	{Comment}   { /* ignore */ }

	/* espaco em branco e erro */
	[ \t\r\n\f] { /* ignore white space. */ }
	. { System.err.println("Illegal character: "+yytext()); }
}

<STRING> {
  \"                             { yybegin(YYINITIAL); 
                                   return sf.newSymbol(string.toString(), sym.TEXTO); }
  [^\n\r\"\\]+                   { string.append( yytext() ); }
  \\t                            { string.append('\t'); }
  \\n                            { string.append('\n'); }
  \\r                            { string.append('\r'); }
  \\\"                           { string.append('\"'); }
  \\                             { string.append('\\'); }
}
